﻿using System;
using System.Collections.ObjectModel;
using System.IO;
using System.Text;
using System.Xml;
using Unknown.Framework.General;
using Unknown.Framework.Transform;

namespace Unknown.Framework.Develop
{
    /// <summary>
    /// 崩溃处理类
    /// </summary>
    public class CrashHandler
    {
        private string _Directory = string.Format(Variable.Culture, "{0}{1}Dump", Variable.Develop, Variable.PathSeparator);
        /// <summary>
        /// 目录
        /// </summary>
        public string Directory
        {
            get
            {
                return this._Directory;
            }
            set
            {
                this._Directory = value;
            }
        }

        private string _Name = "Default";
        /// <summary>
        /// 名称
        /// </summary>
        public string Name
        {
            get
            {
                return this._Name;
            }
            set
            {
                this._Name = value;
            }
        }

        /// <summary>
        /// 持久化
        /// </summary>
        /// <param name="dump">转储数据</param>
        public void Hibernate(Dump dump)
        {
            if (dump != null)
            {
                lock (this)
                {
                    MemoryStream memoryStream = null;

                    try
                    {
                        Collection<Dump> dumps = new Collection<Dump>();
                        dumps.Add(dump);

                        string values = ObjectHandler.SerializeXml(dumps, typeof(Collection<Dump>), false);

                        if (!string.IsNullOrEmpty(values))
                        {
                            byte[] buffer = UTF8Encoding.UTF8.GetBytes(values);

                            memoryStream = new MemoryStream();
                            memoryStream.Write(buffer, 0, buffer.Length);
                            memoryStream.Seek(0, SeekOrigin.Begin);

                            XmlReader xmlReader = XmlReader.Create(memoryStream);

                            XmlDocument xmlDocument = new XmlDocument();
                            xmlDocument.Load(xmlReader);

                            DateTime now = DateTime.Now;
                            string file = string.Format(Variable.Culture, "{0}{1}{2}_{3}-{4}-{5}.xml", this.Directory, Variable.PathSeparator, this.Name, now.Year, now.Month, now.Day);

                            FileInfo fileInfo = new FileInfo(file);
                            if (!fileInfo.Directory.Exists)
                            {
                                fileInfo.Directory.Create();
                            }

                            if (fileInfo.Exists)
                            {
                                XmlDocument currentXmlDocument = new XmlDocument();
                                currentXmlDocument.Load(fileInfo.FullName);
                                xmlDocument.DocumentElement.InnerXml += currentXmlDocument.DocumentElement.InnerXml;
                            }

                            xmlDocument.Save(fileInfo.FullName);
                        }
                    }
                    finally
                    {
                        if (memoryStream != null)
                        {
                            memoryStream.Close();
                        }
                    }
                }
            }
        }

        /// <summary>
        /// 持久化
        /// </summary>
        /// <param name="exception">异常</param>
        public void Hibernate(Exception exception)
        {
            Dump dump = new Dump(exception);
            this.Hibernate(dump);
        }

        /// <summary>
        /// 持久化
        /// </summary>
        /// <param name="exception">异常</param>
        /// <param name="remarks">附注</param>
        public void Hibernate(Exception exception, Collection<string> remarks)
        {
            Dump dump = new Dump(exception, remarks);
            this.Hibernate(dump);
        }
    }
}
